package core.redeNeural;

import static core.redeNeural.RedeNeural.NUM_LAYERS;

import java.util.Random;

import org.encog.neural.activation.ActivationSigmoid;
import org.encog.neural.data.NeuralData;
import org.encog.neural.data.basic.BasicNeuralData;

import core.exception.RedeException;

public class RedeTipo2 extends RedeNeural {

	public RedeTipo2(String codigo){		
		super(codigo.substring(0, 7048));
		if(codigo.length() != 7056)
			try {
				throw new RedeException("Esse é um código de rede tipo 1!");
			} catch (RedeException e) {
				e.printStackTrace();
			}
		double pesoDama = Integer.parseInt(codigo.substring(codigo.length()-8, codigo.length()),2);
		setPesoDama(normalizar(pesoDama/255));
	}
	
	public RedeTipo2(){
		super();
		Random r = new Random();
		double aux = r.nextDouble();
		setPesoDama(normalizar(aux));
		int valorInteiro = (int) (aux*255);
		String pesoBin = Integer.toBinaryString(valorInteiro);
		StringBuilder genePesoDama = new StringBuilder();
		for(int k=0;k<8-pesoBin.length();k++){
			genePesoDama.append("0");
		}
		genePesoDama.append(pesoBin);
		this.setCodigo(this.getCodigo() + genePesoDama);
	}	
	
	private double normalizar(double aux) {
		return (aux*8.9) + 1.1;
	}
	
	public double avaliaTabuleiro(double casas[]){
		double[] casasPesoDama = new double[32];
		double somaSaida = 0;		
		
		//REDE TIPO 2
		for(int i = 0; i<32; i++){
			if(Math.abs(casas[i]) == 2)
				casasPesoDama[i] = (casas[i]/2)*getPesoDama();
			else
				casasPesoDama[i] = casas[i];
			somaSaida += casasPesoDama[i];
		}		
		NeuralData data = new BasicNeuralData(32);
		data.setData(casasPesoDama);
		getNet().compute(data);
		
		for(double a : getNet().getLayers().get(NUM_LAYERS - 2).getFire().getData())
			somaSaida += a;		
		ActivationSigmoid funcaoAtivacao = new ActivationSigmoid();		
		return funcaoAtivacao.activationFunction(somaSaida);
		
	}
	
}
